from PyQt6 import QtCore
from PyQt6 import QtWidgets
from PyQt6 import QtGui

from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QDialog
from PyQt6 import uic

import asyncio
from qasync import asyncSlot, asyncClose
from client_core import QAsyncSsdevClient


class RoleSelectBox(QtWidgets.QComboBox):
    popupAboutToBeShown = pyqtSignal()

    def __init__(self, parent):
        super(RoleSelectBox, self).__init__(parent)
        self.model = QtGui.QStandardItemModel(0, 1)
        self.setModel(self.model)

    def showPopup(self) -> None:
        print('show popup')
        self.popupAboutToBeShown.emit()
        super(RoleSelectBox, self).showPopup()

    def set_roles(self, roles):
        self.model.clear()
        for index, role in enumerate(roles):
            name = role['displayName']

            item = QtGui.QStandardItem(name)
            item.setData(role, QtCore.Qt.ItemDataRole.UserRole)

            self.model.appendRow(item)

    def clear(self) -> None:
        self.model.clear()
        super(RoleSelectBox, self).clear()


class LoginDialog(QDialog):
    errorMessage = pyqtSignal(str)

    def __init__(self, parent, url: str):
        super(LoginDialog, self).__init__(parent)
        uic.loadUi('login.ui', self)

        self.cbRole.popupAboutToBeShown.connect(self.on_role_popup)

        self.client = QAsyncSsdevClient(url, parent=self.parent())
        self.client.receive_error.connect(self.show_error)

    def show_error(self, msg):
        QtWidgets.QMessageBox.critical(self, "Error", msg)

    def clear_combox_role_items(self):
        self.cbRole.clear()

    def _disconnect_all(self):
        self.client.receive_error.disconnect(self.show_error)

    def _accept(self):
        self.parent().client_ok.emit(self.client)
        self._disconnect_all()
        super(LoginDialog, self).accept()

    @asyncSlot()
    async def accept(self) -> None:
        tenant_id = self.eTenantId.text()
        username = self.eUsername.text()

        current_index = self.cbRole.currentIndex()
        role = self.cbRole.itemData(current_index, QtCore.Qt.ItemDataRole.UserRole)
        token = await self.client.fetch_token(tenant_id, username, role)

        self._accept()

    def reject(self) -> None:
        self._disconnect_all()
        super(LoginDialog, self).reject()

    @asyncSlot()
    async def on_role_popup(self):
        tenant_id = self.eTenantId.text()
        username = self.eUsername.text()
        password = self.ePassword.text()

        self.clear_combox_role_items()

        rsp = await self.client.my_roles(tenant_id, username, password)

        self.cbRole.set_roles(rsp)
